#include "SGException.h"

#include <istream>
#include <ostream>
#include <sstream>
#include <utility>

#include <boost/stacktrace/stacktrace.hpp>

using namespace SG::Utility;

// 构造函数，初始化SGException对象
SGException::SGException ()
{
    myMessage = "SGException\n";
    update_what ();
}

// 构造函数，用于创建SGException对象的副本，初始化myMessage成员变量并更新what()返回的字符串
SGException::SGException (const SGException& inst) noexcept : myMessage (inst.myMessage)
{
    update_what ();
}

// 构造函数，初始化SGException对象，接受一个字符串参数sMessage，并调用update_what()方法更新what()方法的返回值
SGException::SGException (const char* sMessage) : myMessage (sMessage)
{
    update_what ();
}

// SGException类的构造函数，接受一个std::string类型的消息作为参数，并将其赋值给成员变量myMessage。
// 调用update_what()方法以更新异常的描述信息。
SGException::SGException (std::string sMessage) : myMessage (std::move (sMessage))
{
    update_what ();
}

// 定义 SGException 类的赋值运算符重载函数
// 参数：const SGException& inst - 另一个 SGException 对象的常量引用
// 返回值：SGException& - 当前对象的引用
// 功能：将传入的 SGException 对象的 myMessage 成员变量赋值给当前对象，并更新 what 字符串
SGException& SGException::operator= (const SGException& inst)
{
    if (this != &inst)
    {  // 检查自赋值
        myMessage = inst.myMessage;
        update_what ();
    }

    return *this;
}

// SGException 类的 what 方法，返回异常信息的 C 风格字符串
const char* SGException::what () const noexcept
{
    return myWhat.c_str ();
}

// SGException类中的info方法，返回一个表示异常信息的字符串
std::string SGException::info () const
{
    return "Exception";
}

// SGException 类中的 message 方法
// 返回 myMessage 成员变量的值
std::string SGException::message () const
{
    return myMessage;
}

// 此函数返回当前异常的堆栈跟踪信息。它使用boost库来获取堆栈跟踪，并将其格式化为字符串返回。
std::string SGException::stacktrace () const
{
    std::stringstream buffer;
    buffer << boost::stacktrace::stacktrace ();
    // std::cout << boost::stacktrace::stacktrace ();
    return buffer.str ();
}

// 该函数更新 what 字符串，该字符串包含异常信息和堆栈跟踪信息。
void SGException::update_what ()
{
    std::stringstream buffer;

    this->print (buffer);

    myWhat = buffer.str ();
}

// 该函数将一个字符串追加到 myMessage 成员变量中，并更新 what 字符串。
void SGException::append_message (const std::string& rMessage)
{
    myMessage.append (rMessage);
    update_what ();
}

// 该函数打印异常信息和堆栈跟踪信息到一个输出流中。
void SGException::print (std::ostream& rOStream) const
{
    rOStream << info ();                          // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
    rOStream << "Error: " << message () << '\n';  // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
    rOStream << "   in: " << stacktrace ();       // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall)
}

// SGException类的成员函数，重载了<<操作符，用于将字符串追加到异常消息中
SGException& SGException::operator<< (const char* rString)
{
    append_message (rString);  // 调用append_message函数，将传入的字符串追加到异常消息中

    return *this;              // 返回当前对象的引用，以便支持链式调用
}

// SGException类的重载操作符<<，用于将标准输出流操作符函数应用到异常消息中
SGException& SGException::operator<< (std::ostream& (*pf) ( std::ostream& ) )
{
    std::stringstream buffer;
    pf (buffer);

    append_message (buffer.str ());

    return *this;
}

// 重载输入流操作符，用于从输入流中读取SGException对象
// 参数: rIStream - 输入流引用, rThis - SGException对象引用
// 返回值: 输入流引用
std::istream& operator>> (std::istream& rIStream, SGException& rThis)  // NOLINT(misc-unused-parameters)
{
    // rThis << rIStream;
    return rIStream;
}

// 重载输出流操作符，用于将SGException对象输出到指定的输出流中
std::ostream& operator<< (std::ostream& rOStream, const SGException& rThis)
{
    rThis.print (rOStream);  // 调用SGException对象的print方法，将异常信息输出到指定的输出流中

    return rOStream;         // 返回输出流对象，以便支持链式调用
}

// RuntimeError

// SGRuntimeError类的构造函数，调用基类SGException的构造函数进行初始化
RuntimeError::RuntimeError () = default;

// 构造函数，用于初始化SGRuntimeError对象，调用基类SGException的构造函数并传递错误信息
RuntimeError::RuntimeError (const char* sMessage) : SGException (sMessage)
{}

// RuntimeError 类的构造函数，接受一个字符串参数 sMessage，用于初始化基类 SGException 的成员变量
RuntimeError::RuntimeError (const std::string& sMessage) : SGException (sMessage)
{}

// 返回RuntimeError字符串的成员函数，用于获取运行时错误的描述信息
std::string RuntimeError::info () const
{
    return "RuntimeError";
}

// TypeError

// TypeError类的构造函数，调用基类SGException的默认构造函数
TypeError::TypeError () = default;

// TypeError类的构造函数，接受一个C风格字符串作为错误信息，并调用基类SGException的构造函数
TypeError::TypeError (const char* sMessage) : SGException (sMessage)
{}

// TypeError类的构造函数，接受一个std::string对象作为错误信息，并调用基类SGException的构造函数
TypeError::TypeError (const std::string& sMessage) : SGException (sMessage)
{}

// ValueError

// 返回TypeError类型的信息字符串，用于获取运行时错误的描述信息
std::string TypeError::info () const
{
    return "TypeError";
}

// ValueError

// ValueError类的构造函数，调用基类 SGException 的默认构造函数
ValueError::ValueError () = default;

// ValueError类的构造函数，接受一个C风格字符串作为错误信息，并调用基类SGException的构造函数
ValueError::ValueError (const char* sMessage) : SGException (sMessage)
{}

// ValueError类的构造函数，接受一个std::string对象作为错误信息，并调用基类SGException的构造函数
ValueError::ValueError (const std::string& sMessage) : SGException (sMessage)
{}

// 返回ValueError字符串的成员函数，用于获取运行时错误的描述信息
std::string ValueError::info () const
{
    return "ValueError";
}

// IndexError

// IndexError类的构造函数，调用基类 SGException 的默认构造函数
IndexError::IndexError () = default;

// IndexError类的构造函数，接受一个C风格字符串作为错误信息，并调用基类SGException的构造函数
IndexError::IndexError (const char* sMessage) : SGException (sMessage)
{}

// IndexError类的构造函数，接受一个std::string对象作为错误信息，并调用基类SGException的构造函数
IndexError::IndexError (const std::string& sMessage) : SGException (sMessage)
{}

// 返回IndexError字符串的成员函数，用于获取运行时错误的描述信息
std::string IndexError::info () const
{
    return "IndexError";
}

// ImportError

// ImportError类的构造函数，调用基类 SGException 的默认构造函数
ImportError::ImportError () = default;

// ImportError类的构造函数，接受一个C风格字符串作为错误信息，并调用基类SGException的构造函数
ImportError::ImportError (const char* sMessage) : SGException (sMessage)
{}

// ImportError类的构造函数，接受一个std::string对象作为错误信息，并调用基类SGException的构造函数
ImportError::ImportError (const std::string& sMessage) : SGException (sMessage)
{}

// 返回ImportError字符串的成员函数，用于获取运行时错误的描述信息
std::string ImportError::info () const
{
    return "ImportError";
}

// ParserError

// ParserError类的构造函数，调用基类 SGException 的默认构造函数
ParserError::ParserError () = default;

// ParserError类的构造函数，接受一个C风格字符串作为错误信息，并调用基类SGException的构造函数
ParserError::ParserError (const char* sMessage) : SGException (sMessage)
{}

// ParserError类的构造函数，接受一个std::string对象作为错误信息，并调用基类SGException的构造函数
ParserError::ParserError (const std::string& sMessage) : SGException (sMessage)
{}

// 返回ParserError字符串的成员函数，用于获取运行时错误的描述信息
std::string ParserError::info () const
{
    return "ParserError";
}

// FileSystemError

FileSystemError::FileSystemError () = default;

FileSystemError::FileSystemError (const char* sMessage) : SGException (sMessage)
{}

FileSystemError::FileSystemError (const std::string& sMessage) : SGException (sMessage)
{}

// 返回ParserError字符串的成员函数，用于获取运行时错误的描述信息
std::string FileSystemError::info () const
{
    return "FileSystemError";
}
